import { filter, isNil, includes } from "lodash";
import React, { useMemo, useState, useEffect } from "react";
import Tree from 'antd/lib/tree';
import { Section } from "@/components/visualizations/editor";
import { EditorPropTypes } from "@/visualizations/prop-types";
import Button from "antd/lib/button";
import { prepareColumns } from "../utils";
import * as Grid from "antd/lib/grid";

export default function HeaderSettings({ options, onOptionsChange }) {
  const [defaultCustomCode, setDefaultCustomCode] = useState([]);
  const [selectedKey, setSelectedKey] = useState("");
  const [selectedTitle, setSelectedTitle] = useState("");

  const [searchTerm, setSearchTerm] = useState("");
  const [orderBy, setOrderBy] = useState([]);
  const searchColumns = useMemo(() => filter(options.columns, "allowSearch"), [options.columns]);
  const tableColumns = useMemo(() => {
    return prepareColumns(options.autoScroll, options.columns, null, orderBy, newOrderBy => {
      setOrderBy(newOrderBy);
    });
  }, [options.columns, searchColumns, orderBy]);

  const onDragEnter = info => {};

  const onDrop = info => {
    const dropKey = info.node.props.eventKey;
    const dragKey = info.dragNode.props.eventKey;
    const dropPos = info.node.props.pos.split('-');
    const dropPosition = info.dropPosition - Number(dropPos[dropPos.length - 1]);

    const loop = (data, key, callback) => {
      data.forEach((item, index, arr) => {
        if (item.key === key) {
          return callback(item, index, arr);
        }
        if (item.children) {
          return loop(item.children, key, callback);
        }
      });
    };
    const data = [...defaultCustomCode];

    // Find dragObject
    let dragObj;
    loop(data, dragKey, (item, index, arr) => {
      arr.splice(index, 1);
      dragObj = item;
    });

    if (!info.dropToGap) {
      // Drop on the content
      loop(data, dropKey, item => {
        item.children = item.children || [];
        // where to insert 示例添加到尾部，可以是随意位置
        item.children.push(dragObj);
      });
    } else if (
      (info.node.props.children || []).length > 0 && // Has children
      info.node.props.expanded && // Is expanded
      dropPosition === 1 // On the bottom gap
    ) {
      loop(data, dropKey, item => {
        item.children = item.children || [];
        // where to insert 示例添加到头部，可以是随意位置
        item.children.unshift(dragObj);
      });
    } else {
      let ar;
      let i;
      loop(data, dropKey, (item, index, arr) => {
        ar = arr;
        i = index;
      });
      if (dropPosition === -1) {
        ar.splice(i, 0, dragObj);
      } else {
        ar.splice(i + 1, 0, dragObj);
      }
    }

    setDefaultCustomCode(data);
  };

  const onSelect = (selectedKeys, e) => {
    setSelectedKey(e.node.key); 
    setSelectedTitle(e.node.title);
  };

  const tableColumnsToTree = () => {
    var keys = [];
    tableColumns.map(col => {
      if (col.key !== '###Redash::Visualizations::Table::Spacer###') {
        keys.push({key: col.key, title: col.key});
      }
    });
    setDefaultCustomCode(keys);
  };

  const newNode = () =>{
    var title = window.prompt("请输入标题：", "合并标题");
    if (!!title) {
      var keys = [...defaultCustomCode];
      keys.push({key: "node::" + Date.now().toString(), title, children: []});
      setDefaultCustomCode(keys);
    }
  }

  const loopRepalce = (cols, title) => {
    cols.forEach((item, index) => {
      if (item.key === selectedKey) {
        item.title = title;
        cols.splice(index, 1, item);
      } else if (item.children && item.children.length>0) {
        item.children = loopRepalce(item.children, title);
        cols.splice(index, 1, item);
      }
    });
    return cols;
  };

  const loopRemove = (cols) => {
    cols.forEach((item, index) => {
      if (item.key === selectedKey) {
        cols.splice(index, 1);
      } else if (item.children && item.children.length>0) {
        item.children = loopRemove(item.children);
        cols.splice(index, 1, item);
      }
    });
    return cols;
  };

  const editNode = () => {
    if (includes(selectedKey, "node::")) {
      var title = window.prompt("请输入标题：", selectedTitle);
      if (!!title && title!=selectedTitle) {
        var keys = [...defaultCustomCode];
        keys = loopRepalce(keys, title);
        setDefaultCustomCode(keys);
      }
    } else {
      window.alert("新建节点可以编辑，原有节点请到列设置下更改。");
    }
  }

  const deleteNode = () => {
    if (window.confirm("确定删除节点”" + selectedTitle + "”？")) {
      var keys = [...defaultCustomCode];
      keys = loopRemove(keys);
      setDefaultCustomCode(keys);
      setSelectedKey("");
    }
  }

  const saveNode = () =>{
    if (window.confirm("确定提交以便保存？")) {
      var keystr = defaultCustomCode.map((item) => JSON.stringify(item)).join(";");
      onOptionsChange({ customCode: keystr });
    }
  }

  useEffect(()=>{
    if (options && !isNil(options.customCode) && options.customCode) {
      var keys = [];
      var arrs = options.customCode.split(";");
      arrs.map((arr)=>{
        keys.push(JSON.parse(arr));
      });
      setDefaultCustomCode(keys);
    }  
  }, [options])

  return (
    <React.Fragment>
      <Section>
        <Tree
          className="draggable-tree"
          draggable
          blockNode
          showLine
          defaultExpandAll
          onDragEnter={onDragEnter}
          onDrop={onDrop}
          onSelect={onSelect}
          treeData={defaultCustomCode}
          height={400}
        />
      </Section>
      <Section>
        <Grid.Row gutter={15}>
          <Grid.Col span={10}>
            <Button onClick={() => tableColumnsToTree()}>生成默认表头</Button>
            <Button onClick={() => setDefaultCustomCode([])}>清空</Button>
          </Grid.Col>
          <Grid.Col span={14}>
            <Button onClick={() => newNode()}>新建节点</Button>
            <Button onClick={() => editNode()}>编辑节点</Button>
            <Button onClick={() => deleteNode()}>删除节点</Button>
            <Button onClick={() => saveNode()}>提交</Button>
          </Grid.Col>
        </Grid.Row>
      </Section>
    </React.Fragment>
  );
}

HeaderSettings.propTypes = EditorPropTypes;
